#include "lib/udpserver.h"
#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <set>
#include <map>
#include <string>
#include <string.h>

using namespace std;

int GenerarPalabras( map<int,string> &palabra) //Creamos una variable map donde almacenamos todas las palabras
{                                              //y a cada palabra le asignamos un número.

    palabra[1]="cacafuti";
    palabra[2]="esternocleidomastoideo";
    palabra[3]="anaconda";
    palabra[4]="endoplasmatico";
    palabra[5]="yuxtaposicion";
    palabra[6]="endocrino";
    palabra[7]="defenestración";
    palabra[8]="desoxirribonucleico";
    palabra[9]="amigdalitis";
    palabra[10]="baluarte";
    palabra[11]="silogismo";
    palabra[12]="alderaan";
    palabra[13]="osteoporosis";
    palabra[14]="anatidaefobia";
    palabra[15]="conjuntivitis";
    palabra[16]="transformador";
    palabra[17]="el silencio de los corderos";
    palabra[18]="la guerra de las galaxias";
    palabra[19]="el señor de los anillos";
    palabra[20]="spiderman";
    palabra[21]="callate meg";
    palabra[22]="el caballero oscuro";
    palabra[23]="la bella y la bestia";
    palabra[24]="pocahontas 2";
    palabra[25]="como podeis ver me aburro muchisimo";

    return (palabra.size());
}

int ElegirPalabra (int tam, bool &resuelto)         //Aleatoriamente elegimos una palabra.
{
    srand ( time(NULL) );
    resuelto=false;
    return (rand() % tam + 1);
}

void GenerarSacoLetras(set<char> &letras, string palabra)
{
    for(int i=0; i<palabra.length();i++)   //Generamos un set donde almacenamos cada letra distinta que aparece en la palabra
    {
        if (strncmp(&palabra.at(i)," ",1)!=0)
            letras.insert(palabra.at(i));
    }
}

void GenerarPalabraVacia (string &palabra, int length, string palabra_secreta) //Generamos una palabra llena de guiones
{                                                                              //sobre la que se van a ir poniendo las
    for(int i=0; i<length;i++)                                                 //letras según se acierten
    {
        if (strncmp(&palabra_secreta.at(i)," ",1)==0)
            palabra.append(1,' ');
        else
            palabra.append(1,'_');
    }
}

void LetrasDichas(char* letra, string &dichas)
{
    dichas.append(1,' ');
    dichas.append(letra);
}

bool ComprobarLetra(char* letra, string palabra, string &progreso_palabra, set<char> &sacoletras)
{
    for (int i=0; i<progreso_palabra.length(); i++)              //Comprobamos que la letra que nos dan
    {                                                            //pertenece a la palabra.
        if (palabra.compare(i,1,letra)==0)
            progreso_palabra.replace(i,1,letra);
    }
    if(sacoletras.count(*letra)>0)   //--------------> Si la letra está en el saco la sacamos para saber
    {                                //                cuantas letras faltan.
        char a = *letra;
        sacoletras.erase(a);
        return true;
    }
    if (sacoletras.count(*letra)==0)
        return false;
}

void AsignarAhorcado(int vidas, string &ahorcado)  //Dibujamos el ahorcado en función de las vidas que queden.
{
    switch (vidas)
    {
    case 0:
    {
        ahorcado.clear();
        ahorcado.assign("╔═════╤  \n║     │  \n║     O  \n║    /|\\\n║    / \\\n║          \n╩══════════");
        break;
    }
    case 1:
    {
        ahorcado.clear();
        ahorcado.assign("╔═════╤  \n║     │  \n║     O  \n║    /|\\\n║    /   \n║          \n╩══════════");
        break;
    }
    case 2:
    {
        ahorcado.clear();
        ahorcado.assign("╔═════╤  \n║     │  \n║     O  \n║    /|\\\n║        \n║          \n╩══════════");
        break;
    }
    case 3:
    {
        ahorcado.clear();
        ahorcado.assign("╔═════╤  \n║     │  \n║     O  \n║    /|  \n║        \n║          \n╩══════════");
        break;
    }
    case 4:
    {
        ahorcado.clear();
        ahorcado.assign("╔═════╤  \n║     │  \n║     O  \n║     |  \n║        \n║          \n╩══════════");
        break;
    }
    case 5:
    {
        ahorcado.clear();
        ahorcado.assign("╔═════╤  \n║     │  \n║     O  \n║        \n║        \n║          \n╩══════════");
        break;
    }
    case 6:
    {
        ahorcado.clear();
        ahorcado.assign("╔═════╤  \n║     │  \n║        \n║        \n║        \n║          \n╩══════════");
        break;
    }
    }

}

void ComprobarComando(string comando, string palabra, string &progreso_palabra,set<char> &sacoletras, string &salida,bool &resuelto,int &vidas, string &ahorcado, string &letras_dichas)
{
    if (comando.compare(0,5,"letra")==0)
    {
        if (ComprobarLetra (&comando[6],palabra,progreso_palabra,sacoletras)==1)
        {
            salida.assign("La letra es correcta");
            if (sacoletras.empty())
            {
                resuelto=true;
                salida.assign("Enhorabuena, ha adivinado la palabra");
            }

        }
        else
        {
            salida.assign("La letra no es correcta");
            vidas--;
            LetrasDichas (&comando[6],letras_dichas);
        }
    }
    else
        if (comando.compare(0,8,"solucion")==0)
        {
            if (comando.find(palabra)!= string::npos)
            {
                salida.assign("Enhorabuena, ha adivinado la palabra");
                progreso_palabra=palabra;
                resuelto=true;
            }
            else
            {
                salida.assign("Lo siento, no es la solución correcta");
                vidas--;
            }

        }
        else
        {
            if (comando.compare(0,4,"exit")==0)
                exit(1);

            else
                salida.assign("No se reconoce el comando. Los comandos admitidos son 'letra' y 'solucion' seguidos de su respuesta");
        }
    AsignarAhorcado (vidas,ahorcado);
}

int main(int argc, char* argv[])
{
    int num,tam,length,vidas=6;
    string progreso_palabra,ahorcado, salida, letras_dichas;
    bool resuelto=false;
    map<int,string> palabra_secreta;
    set <char> letras;

    UDPserver server;
    tam = GenerarPalabras (palabra_secreta);
    num=ElegirPalabra (tam,resuelto);
    length=palabra_secreta[num].length();
    GenerarSacoLetras (letras,palabra_secreta[num]);
    progreso_palabra.clear();
    GenerarPalabraVacia (progreso_palabra, length, palabra_secreta[num]);
    AsignarAhorcado (vidas, ahorcado);
    letras_dichas.clear();
    letras_dichas.append("Letras dichas: ");

    server.checkConnection(argc);
    server.socket(argv);
    server.recibir();
    if (server.getSbuffer().compare("jugar")==0)
    {

        while(!resuelto)
        {
            salida.clear();
            server.enviar (ahorcado);
            server.enviar (progreso_palabra);
            server.enviar (letras_dichas);
            if (vidas==0)
            {
                server.enviar ("Lo siento, ha perdido");
                exit(1);
            }
            server.enviar ("Introduzca un comando: ");
            server.recibir ();
            ComprobarComando (server.getSbuffer(),palabra_secreta[num],progreso_palabra,letras,salida,resuelto,vidas,ahorcado,letras_dichas);
            server.enviar (salida);


        }
        server.enviar (palabra_secreta[num]);
    }



return(0);
}

